package com.platform.apex.cma.config;

import java.time.Duration;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import com.typesafe.config.Config;
import com.typesafe.config.ConfigList;
import com.typesafe.config.ConfigMemorySize;
import com.typesafe.config.ConfigMergeable;
import com.typesafe.config.ConfigObject;
import com.typesafe.config.ConfigOrigin;
import com.typesafe.config.ConfigResolveOptions;
import com.typesafe.config.ConfigValue;

public class TypesafeConfig implements Config {

	private final com.typesafe.config.Config delegate;

	protected TypesafeConfig(final com.typesafe.config.Config config) {
		this.delegate = config;
	}

	@Override
	public boolean hasPath(final String path) {
		return delegate.hasPath(path);
	}

	@Override
	public boolean isEmpty() {
		return delegate.isEmpty();
	}

	@Override
	public Number getNumber(final String path) {
		return delegate.getNumber(path);
	}

	public Number getNumberByDefault(final String path, Number defaultValue) {

		if (hasPath(path)) {
			return delegate.getNumber(path);
		} else {
			return defaultValue;
		}
	}

	@Override
	public boolean getBoolean(final String path) {
		return delegate.getBoolean(path);
	}

	public boolean getBooleanByDefault(final String path, Boolean defaultValue) {
		if (hasPath(path)) {
			return delegate.getBoolean(path);
		} else {
			return defaultValue;
		}
	}

	@Override
	public int getInt(final String path) {
		return delegate.getInt(path);
	}

	public int getIntByDefault(final String path, int defaultValue) {
		if (hasPath(path)) {
			return delegate.getInt(path);
		} else {
			return defaultValue;
		}
	}

	@Override
	public long getLong(final String path) {
		return delegate.getLong(path);
	}

	public long getLongByDefault(final String path, long defaultValue) {
		if (hasPath(path)) {
			return delegate.getLong(path);
		} else {
			return defaultValue;
		}
	}

	@Override
	public double getDouble(final String path) {
		return delegate.getDouble(path);
	}

	public double getDoubleByDefault(final String path, double defaultValue) {
		if (hasPath(path)) {
			return delegate.getDouble(path);
		} else {
			return defaultValue;
		}
	}

	@Override
	public String getString(final String path) {
		return delegate.getString(path);
	}

	public String getStringByDefault(final String path, String defaultValue) {
		if (hasPath(path)) {
			return delegate.getString(path);
		} else {
			return defaultValue;
		}
	}

	@Override
	public Config getConfig(final String path) {
		return new TypesafeConfig(delegate.getConfig(path));
	}

	@Override
	public Object getAnyRef(final String path) {
		return delegate.getAnyRef(path);
	}

	@Override
	public Long getBytes(final String path) {
		return delegate.getBytes(path);
	}

	@Override
	public long getDuration(final String path, final TimeUnit unit) {
		return delegate.getDuration(path, unit);
	}

	@Override
	public List<Boolean> getBooleanList(final String path) {
		return delegate.getBooleanList(path);
	}

	public List<Boolean> getBooleanListByDefault(final String path,
			List<Boolean> defaultValue) {
		if (hasPath(path)) {
			return delegate.getBooleanList(path);
		} else {
			return defaultValue;
		}
	}

	@Override
	public List<Number> getNumberList(final String path) {
		return delegate.getNumberList(path);
	}

	public List<Number> getNumberListByDefault(final String path,
			List<Number> defaultValue) {
		if (hasPath(path)) {
			return delegate.getNumberList(path);
		} else {
			return defaultValue;
		}
	}

	@Override
	public List<Integer> getIntList(final String path) {
		return delegate.getIntList(path);
	}

	public List<Integer> getIntListByDefault(final String path,
			List<Integer> defaultValue) {
		if (hasPath(path)) {
			return delegate.getIntList(path);
		} else {
			return defaultValue;
		}
	}

	@Override
	public List<Long> getLongList(final String path) {
		return delegate.getLongList(path);
	}

	public List<Long> getLongListByDefault(final String path,
			List<Long> defaultValue) {
		if (hasPath(path)) {
			return delegate.getLongList(path);
		} else {
			return defaultValue;
		}
	}

	@Override
	public List<Double> getDoubleList(final String path) {
		return delegate.getDoubleList(path);
	}

	public List<Double> getDoubleListByDefault(final String path,
			List<Double> defaultValue) {
		if (hasPath(path)) {
			return delegate.getDoubleList(path);
		} else {
			return defaultValue;
		}
	}

	@Override
	public List<String> getStringList(final String path) {
		return delegate.getStringList(path);
	}

	public List<String> getStringListByDefault(final String path,
			List<String> defaultValue) {
		if (hasPath(path)) {
			return delegate.getStringList(path);
		} else {
			return defaultValue;
		}
	}

	@Override
	public List<?> getAnyRefList(final String path) {
		return delegate.getAnyRefList(path);
	}

	@Override
	public List<Long> getBytesList(final String path) {
		return delegate.getBytesList(path);
	}

	@Override
	public List<Long> getDurationList(final String path, final TimeUnit unit) {
		return delegate.getDurationList(path, unit);
	}

	@Override
	public ConfigObject root() {
		return delegate.root();
	}

	@Override
	public ConfigOrigin origin() {
		return delegate.origin();
	}

	@Override
	public Config withFallback(ConfigMergeable other) {
		return delegate.withFallback(other);
	}

	@Override
	public Config resolve() {
		return delegate.resolve();
	}

	@Override
	public Config resolve(ConfigResolveOptions options) {
		return delegate.resolve(options);
	}

	@Override
	public boolean isResolved() {
		return delegate.isResolved();
	}

	@Override
	public Config resolveWith(Config source) {
		return delegate.resolveWith(source);
	}

	@Override
	public Config resolveWith(Config source, ConfigResolveOptions options) {
		return delegate.resolveWith(source, options);
	}

	@Override
	public void checkValid(Config reference, String... restrictToPaths) {
		delegate.checkValid(reference, restrictToPaths);
	}

	@Override
	public boolean hasPathOrNull(String path) {
		return delegate.hasPathOrNull(path);
	}

	@Override
	public Set<Entry<String, ConfigValue>> entrySet() {
		return delegate.entrySet();
	}

	@Override
	public boolean getIsNull(String path) {
		return delegate.getIsNull(path);
	}

	@Override
	public ConfigObject getObject(String path) {
		return delegate.getObject(path);
	}

	@Override
	public ConfigValue getValue(String path) {
		return delegate.getValue(path);
	}

	@Override
	public ConfigMemorySize getMemorySize(String path) {
		return delegate.getMemorySize(path);
	}

	@Override
	public Long getMilliseconds(String path) {
		return delegate.getMilliseconds(path);
	}

	@Override
	public Long getNanoseconds(String path) {
		return delegate.getNanoseconds(path);
	}

	@Override
	public Duration getDuration(String path) {
		return delegate.getDuration(path);
	}

	@Override
	public ConfigList getList(String path) {
		return delegate.getList(path);
	}

	@Override
	public List<? extends Config> getConfigList(String path) {
		return delegate.getConfigList(path);
	}

	@Override
	public List<ConfigMemorySize> getMemorySizeList(String path) {
		return delegate.getMemorySizeList(path);
	}

	@Override
	public List<Long> getMillisecondsList(String path) {
		return delegate.getMillisecondsList(path);
	}

	@Override
	public List<Long> getNanosecondsList(String path) {
		return delegate.getNanosecondsList(path);
	}

	@Override
	public List<Duration> getDurationList(String path) {
		return delegate.getDurationList(path);
	}

	@Override
	public Config withOnlyPath(String path) {
		return delegate.withOnlyPath(path);
	}

	@Override
	public Config withoutPath(String path) {
		return delegate.withoutPath(path);
	}

	@Override
	public Config atPath(String path) {
		return delegate.atPath(path);
	}

	@Override
	public Config atKey(String key) {
		return delegate.atKey(key);
	}

	@Override
	public Config withValue(String path, ConfigValue value) {
		return delegate.withValue(path, value);
	}

	@Override
	public List<? extends ConfigObject> getObjectList(String path) {
		return delegate.getObjectList(path);
	}
}
